package com.myzl.quartz.task;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.myzl.coal.client.BaseHandler;
import com.myzl.coal.client.device.CallBackR2000;
import com.myzl.coal.client.parse.SievePlcParse;
import com.myzl.coal.domain.Device;
import com.myzl.coal.domain.RealTimeData;
import com.myzl.coal.dto.CmdDTO;
import com.myzl.coal.mapper.CommandRecordMapper;
import com.myzl.coal.mapper.DeviceMapper;
import com.myzl.coal.mq.MqService;
import com.myzl.coal.service.ICommandRecordService;
import com.myzl.coal.service.IDeviceService;
import com.myzl.coal.service.IRealTimeDataService;
import com.myzl.coal.service.impl.DemoService;
import com.myzl.coal.service.protocol.CmdService;
import com.myzl.coal.service.protocol.SievePlcCmdService;
import com.myzl.coal.utils.HexUtil;
import com.myzl.common.enums.*;
import com.myzl.quartz.service.ISysJobLogService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * @author Administrator
 * @date 2022年10月25日14:45:52
 */
@Component("commandTask")
@Slf4j
@Data
public class CommandTask {

    private final CmdService cmdService;
    private final SievePlcCmdService sievePlcCmdService;
    private final CommandRecordMapper commandRecordMapper;
    private final ICommandRecordService commandRecordService;
    private final DeviceMapper deviceMapper;
    private final IDeviceService deviceService;
    private final ISysJobLogService jobLogService;
    private final MqService mqService;
    private final IRealTimeDataService realTimeDataService;
    private final DemoService demoService;
    private final SievePlcParse sievePlcParse;
    private final CallBackR2000 callBackR2000;


    public void sendReadCommand() {
        List<Device> deviceList = deviceMapper.selectList(new LambdaQueryWrapper<Device>()
                .eq(Device::getDeviceType, DeviceTypeEnum.DOUBLE_ORDER.getCode())
                .eq(Device::getDeviceStatus, DeviceStatusEnum.ONLINE.getCode()));
        for (Device device : deviceList) {
            // 读取设备瞬时体积
            cmdService.read(new CmdDTO(DeviceTypeEnum.DOUBLE_ORDER.getCode(), device.getId(), DeviceCommandEnum.DEVICE_CURRENT_VOLUME.getCode(), DeviceCommandEnum.DEVICE_CURRENT_VOLUME.getNumber(),DeviceCommandEnum.DEVICE_CURRENT_VOLUME.getInfo()));
            // 读取设备累计体积
            cmdService.read(new CmdDTO(DeviceTypeEnum.DOUBLE_ORDER.getCode(), device.getId(), DeviceCommandEnum.DEVICE_CUMULATIVE_VOLUME.getCode(), DeviceCommandEnum.DEVICE_CUMULATIVE_VOLUME.getNumber(),DeviceCommandEnum.DEVICE_CUMULATIVE_VOLUME.getInfo()));
//            // 读取设备速度
            cmdService.read(new CmdDTO(DeviceTypeEnum.DOUBLE_ORDER.getCode(), device.getId(), DeviceCommandEnum.UNIFORM_SPEED.getCode(), DeviceCommandEnum.UNIFORM_SPEED.getNumber(),DeviceCommandEnum.UNIFORM_SPEED.getInfo()));
//            // 读取设备密度
            cmdService.read(new CmdDTO(DeviceTypeEnum.DOUBLE_ORDER.getCode(), device.getId(), DeviceCommandEnum.VARIABLE_SPEED.getCode(), DeviceCommandEnum.VARIABLE_SPEED.getNumber(),DeviceCommandEnum.VARIABLE_SPEED.getInfo()));
//            // 运行模式
            cmdService.read(new CmdDTO(DeviceTypeEnum.DOUBLE_ORDER.getCode(), device.getId(), DeviceCommandEnum.OPERATE_MODE.getCode(), DeviceCommandEnum.OPERATE_MODE.getNumber(),DeviceCommandEnum.OPERATE_MODE.getInfo()));
        }
    }

    public void commandTimeOut() {
        try {
            cmdService.cmdTimeOut();
        } catch (Exception e) {
            log.info("命令超时定时器执行异常:", e);
        }
    }

    public void sievePlcCmd() {

        Device device = new Device();
        device.setDeviceType(DeviceTypeEnum.SIEVE_PLC.getCode());
        device.setDeviceStatus(DeviceStatusEnum.ONLINE.getCode());
        List<Device> devices = deviceService.selectDeviceList(device);
        devices.forEach(e -> {
            if (demoService.getRedisPoliceFlag(DemoEnum.motor_temperature) || demoService.getRedisPoliceFlag(DemoEnum.exciter_temperature)) {
                String str = "";

                if (demoService.getRedisPoliceFlag(DemoEnum.motor_temperature)) {
                    str = "0E6F0000007B01037800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B9088F3140426666" + "42C80000420C4949" + "000000000000" + "00010000" + "000000000000000000000000000000000000000000000000000000000000000000000000";
                }
                if (demoService.getRedisPoliceFlag(DemoEnum.exciter_temperature)) {
                    str = "0E6F0000007B01037800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B9088F3140426666" + "42183F4B42C80000" + "000000000000" + "00000001" + "000000000000000000000000000000000000000000000000000000000000000000000000";
                }
                if (demoService.getRedisPoliceFlag(DemoEnum.motor_temperature) && demoService.getRedisPoliceFlag(DemoEnum.exciter_temperature)) {
                    str = "0E6F0000007B01037800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B9088F3140426666" + "42C8000042C80000" + "000000000000" + "00010001" + "000000000000000000000000000000000000000000000000000000000000000000000000";
                }
                byte[] bytes = HexUtil.hexStringToByteArray(str);
                sievePlcParse.channelRead(bytes, e.getId());
                sievePlcCmdService.getAddressZero(e.getId());
                return;
            }
            sievePlcCmdService.getAll(e.getId());
        });
    }


    public void deviceStatus() {
        try {
            Device deviceQuery = new Device();
            deviceQuery.setDeviceStatus(DeviceStatusEnum.ONLINE.getCode());
            List<Device> devices = deviceMapper.selectDeviceList(deviceQuery);
            if (CollectionUtils.isEmpty(devices)) {
                return;
            }

            devices.forEach(e -> {
                LocalDateTime dateTime = null;
                Integer deviceId = e.getId();
//                if (BaseHandler.TIME_MAP.containsKey(deviceId)) {
//                    dateTime = BaseHandler.TIME_MAP.get(deviceId);
                    LambdaQueryWrapper<RealTimeData> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(RealTimeData::getDeviceId, deviceId);
                    queryWrapper.eq(RealTimeData::getDictValue, CurrencyEnum.REPORTING_TIME.getCode());
                    queryWrapper.orderByDesc(RealTimeData::getUpdateTime);
                    queryWrapper.last("limit 1");
                    RealTimeData realTimeData = realTimeDataService.getBaseMapper().selectOne(queryWrapper);

                    if (realTimeData != null) {
                        dateTime = LocalDateTimeUtil.of(realTimeData.getUpdateTime());
                }

                if (dateTime == null || dateTime.plusMinutes(BaseHandler.TIME_OUT).isBefore(LocalDateTime.now())) {
                    log.info(dateTime.format(DateTimeFormatter.ISO_DATE_TIME));
                    mqService.sendDeviceStatusOffline(deviceId);

                    switch (DeviceTypeEnum.getValue(e.getDeviceType())) {
                        case SIEVE_PLAT:
                            callBackR2000.connect(e.getIp(), e.getPort());
                        default:
                    }
                }

            });
        } catch (Exception e) {
            log.info("设备状态定时器执行异常:", e);
        }

    }


    public void commandFail() {
        LocalDateTime now = LocalDateTime.now().minusSeconds(60);
        String time = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        commandRecordMapper.cmdFail(time);
    }

    public void clearLog() {
        jobLogService.clearLog();
    }
}
